package com.zry.service.archives;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zry.VO.ArticleYearVo;
import com.zry.entity.Blog;
import com.zry.mapper.BlogMapper;
import com.zry.service.blog.IBlogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ArchivesServiceImpl implements IArchivesService {

    //TODO 需要花时间再看一遍具体消化

    @Autowired
    private IBlogService blogService;

    @Autowired
    private BlogMapper blogMapper;


    @Override
    public List<ArticleYearVo> findBlogByYear() {

        List<Integer> blogByYear = blogMapper.findBlogByYear();

        List<ArticleYearVo> articleYearVoList = blogByYear.stream().map(year -> {
            ArticleYearVo articleYearVo = new ArticleYearVo();

            articleYearVo.setYear(year);

            IPage<Blog> blogByPage = this.findBlogByPageMain(year, 1, 3);
            List<Blog> recordsList = blogByPage.getRecords();

            if (!CollectionUtils.isEmpty(recordsList)) {
                List<Map<String, Object>> blogList = recordsList.stream().map(blog -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("id", blog.getId());
                    map.put("title", blog.getTitle());
                    map.put("createTime", blog.getCreateTime());
                    return map;
                }).collect(Collectors.toList());
                articleYearVo.setBlogList(blogList);
            } else {
                articleYearVo.setBlogList(new ArrayList<>());
            }

            Map<String, Object> pageMap = new HashMap<>();
            pageMap.put("total", blogByPage.getTotal());
            pageMap.put("pages", blogByPage.getPages());
            pageMap.put("pageNo", blogByPage.getCurrent());
            pageMap.put("pageSize", blogByPage.getPages());
            articleYearVo.setPageMap(pageMap);

            return articleYearVo;
        }).sorted((a, b) -> a.getYear() - b.getYear()).collect(Collectors.toList());

        return articleYearVoList;
    }

    public IPage<Blog> findBlogByPageMain(Integer year, Integer pageNo, Integer pageSize) {
        IPage<Blog> page = new Page<>(pageNo, pageSize);

        QueryWrapper<Blog> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "title", "create_time");
        queryWrapper.eq("DATE_FORMAT( create_time, '%Y' )", year);
        queryWrapper.eq("status", 1);
        queryWrapper.eq("is_delete", 0);
        queryWrapper.orderByDesc("create_time");

        return blogMapper.selectPage(page, queryWrapper);
    }

    @Override
    public List<Map<String,Object>> findBlogByPageNo(Integer year, Integer pageNo, Integer pageSize) {
        IPage<Blog> blogByPageMain = findBlogByPageMain(year, pageNo, pageSize);

        if(CollectionUtils.isEmpty(blogByPageMain.getRecords())){
            return new ArrayList<>();
        }

        return blogByPageMain.getRecords().stream().map(blog -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", blog.getId());
            map.put("title", blog.getTitle());
            map.put("createTime", blog.getCreateTime());
            return map;
        }).collect(Collectors.toList());
    }


    /**
     * 分割线
     * =============================================================================================
     * 以下方法都是 文章归档测试使用
     *
     * @return
     */

    @Override
    public List<Map<String, Object>> queryBlog() {
        LambdaQueryWrapper<Blog> queryWrapper = new LambdaQueryWrapper<>();

        // 按需加载
        //queryWrapper.select(Blog::getCreateTime,Blog::getUpdateTime);

        // 可以自定义 除某个字段外的所有字段
        // 传参(class类,不需要的字段)
        queryWrapper.eq(Blog::getStatus, 1);
        queryWrapper.select(Blog.class, blog -> !"content".equals(blog.getColumn()) && !"status".equals(blog.getColumn()));

        List<Blog> list = blogService.list(queryWrapper);

        /**
         * Collectors.groupingBy() 和 Collectors.groupingByConcurrent() 返回的 HashMap ConcurrentHashMap 都是乱序的
         * 要想有序得 new个TreeMap 但是TreeMap 的有序只在初始化时候有效
         * 因此只能遍历插入值
         */
        Map<Integer, List<Blog>> collect2 = list.stream().collect(Collectors.groupingBy(blog -> blog.getCreateTime().getYear(), TreeMap::new, Collectors.toList()));

        List<Map<String, Object>> collect = collect2.entrySet().stream().map(entry -> {
            Map<String, Object> map = new HashMap<>();
            map.put("year", entry.getKey());
            map.put("articleList", entry.getValue());
            return map;
        }).sorted((o1, o2) -> (int) o2.get("year") - (int) o1.get("year")).collect(Collectors.toList());

        return collect;
    }

    @Deprecated
    private TreeMap<Integer, List<Blog>> sortedTreeMap(TreeMap<Integer, List<Blog>> collect2) {
        TreeMap<Integer, List<Blog>> collect1 = new TreeMap<>((o1, o2) -> o1 - o2);

        for (Map.Entry<Integer, List<Blog>> integerListEntry : collect2.entrySet()) {
            collect1.put(integerListEntry.getKey(), integerListEntry.getValue());
        }

        return collect1;
    }

    // 第二种做法定义VO实体类 List<Map<String,list<Blog>>>
    @Override
    public List<ArticleYearVo> queryBlog2() {
        LambdaQueryWrapper<Blog> queryWrapper = new LambdaQueryWrapper<>();

        // 按需加载
        //queryWrapper.select(Blog::getCreateTime,Blog::getUpdateTime);

        // 可以自定义 除某个字段外的所有字段
        // 传参(class类,不需要的字段)
        queryWrapper.eq(Blog::getStatus, 1);
        queryWrapper.select(Blog.class, blog -> !"content".equals(blog.getColumn()) && !"status".equals(blog.getColumn()));

        List<Blog> list = blogService.list(queryWrapper);

        TreeMap<Integer, List<Blog>> collect2 = list.stream().collect(Collectors.groupingBy(blog -> blog.getCreateTime().getYear(), TreeMap::new, Collectors.toList()));

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        List<ArticleYearVo> articleYearVoList = collect2.entrySet().stream().map(entry -> {
            ArticleYearVo articleYearVo = new ArticleYearVo();
            articleYearVo.setYear(entry.getKey());
            List<Blog> blogList = entry.getValue();

            List<Map<String, Object>> collect = blogList.stream().map(blog -> {
                Map<String, Object> map = new HashMap<>();
                map.put("id", blog.getId());
                map.put("title", blog.getTitle());
                map.put("createTime", dtf.format(blog.getCreateTime()));
                return map;
            }).collect(Collectors.toList());

            articleYearVo.setBlogList(collect);

            return articleYearVo;
        }).sorted((o1, o2) -> o2.getYear() - o1.getYear()).collect(Collectors.toList());

        return articleYearVoList;
    }

    @Override
    public List<Map<String, Object>> findBlogGroupByYear() {
        List<String> blogList = blogMapper.findBlogGroupByYear();

        List<Map<String, Object>> collect = blogList.stream().map(year -> {
            Map<String, Object> map = new HashMap<>();
            IPage<Blog> blogPage = findChildrenBlogByYear(Integer.parseInt(year), 1, 10);
            map.put("year", year);
            map.put("total", blogPage.getTotal());
            map.put("pages", blogPage.getCurrent());
            map.put("current", blogPage.getSize());
            map.put("blogList", CollectionUtils.isEmpty(blogPage.getRecords()) ? new ArrayList<>() : blogPage.getRecords());
            return map;
        }).collect(Collectors.toList());

        return collect;
    }


    public IPage<Blog> findChildrenBlogByYear(Integer year, int pageNo, int pageSize) {
        // 创建分页
        IPage<Blog> page = new Page<>(pageNo, pageSize);

        QueryWrapper<Blog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("kb.is_delete", 0);
        queryWrapper.eq("kb.status", 1);
        queryWrapper.eq("DATE_FORMAT(kb.create_time, '%Y')", year);

        return blogMapper.findByPage(page, year, queryWrapper);

    }

}